%include "io.inc"

section .data
msg db "please input two numbers divided by a blank:", 0h

section .bss
input: resb 255
sum: resb 255
temp_sum: resb 255
num1: resb 255
num2: resb 255
temp_num1: resb 255
carry: resb 1   ;进位
len_num1: resb 4
len_num2: resb 4
len_sum: resb 4
temp_len1: resb 4
temp_len2: resb 4


 
section .text
global CMAIN
CMAIN:
    mov ebp, esp; for correct debugging
    PRINT_STRING msg
    NEWLINE
    mov dword[len_num1], 0
    mov dword[len_num2], 0
    ;获取输入的数据
    mov eax, 3
    mov ebx, 0
    mov ecx, input
    mov edx, 255
    int 80h
    
    mov edi, 0  ;counter
    mov eax, num1
    

;获取第一个数字
getnum1:
    mov ebx, ecx
    cmp byte[ecx], " "
    je createnum1
    inc edi
    inc ecx
    ;mov dword[len_num1], edi
    add dword[len_num1], 1
    jmp getnum1

;赋值第一个数字
createnum1:
    dec ebx ;因为在getnum1中跳转到该方法时byte[ebx]为“ ”，所以先要减1
    cmp edi, 0
    je init_eax
    mov dl, byte[ebx]
    mov byte[eax+edi-1], dl ;num1
    dec edi
    jmp createnum1
    
init_eax:
    mov eax, num2
    
getnum2:
    inc ecx
    cmp byte[ecx], 10
    je createnum2
    inc edi
    add dword[len_num2], 1
    jmp getnum2
    
createnum2:
    dec ecx
    cmp edi, 0
    je addfunc
    mov dl, byte[ecx]
    mov byte[eax+edi-1], dl
    dec edi
    jmp createnum2
    
addfunc:
    mov eax, dword[len_num1]
    mov dword[temp_len1], eax
    mov eax, dword[len_num2]
    mov dword[temp_len2], eax
    mov eax, num1
    mov ebx, num2
    mov dword[len_sum], 0
    mov esi, dword[len_num1]
    cmp esi, dword[len_num2]
    jb beforeadd
f1:    mov edi, temp_sum
    mov byte[carry], 0   ;初始化进位0
    jmp addloop
    
beforeadd:  ;num1比num2位数少的情况
    mov eax, num2
    mov ebx, num1
    mov ecx, dword[len_num1]
    mov esi, dword[len_num2]
    mov dword[temp_len1], esi
    mov dword[temp_len2], ecx
    jmp f1
    
addloop:
    cmp dword[temp_len1], 0    ;第一个数字的最高位已经进行过运算时跳转（加法循环结束）
    je addfinal
    mov esi, dword[temp_len1]
    mov cl, byte[eax+esi-1]
    sub cl, 48
    add cl, byte[carry]
    mov esi, dword[temp_len2]
    mov dl, byte[ebx+esi-1]
    sub dl, 48
    cmp dword[temp_len2], 0    ;如果第二个数字最高位已经加过，那么接下来都是用0和第一个数字加
    jna set_dl_0
f2:    add cl, dl
    ;mov byte[carry], 0
    cmp cl, 10  ;如果加起来的数字大于10，说明有进位
    jnb withcarry
    
nocarry:
    mov byte[carry], 0   ;进位0
    add cl, 48  ;+48
    mov byte[edi], cl   ;保存在temp_sum所在的内存
    inc edi
    add dword[len_sum], 1
    sub dword[temp_len1], 1
    sub dword[temp_len2], 1
    jmp addloop
    
withcarry:
    mov byte[carry], 1   ;进位1
    sub cl, 10  ;加起来的数字减10
    add cl, 48  ;+48
    mov byte[edi], cl   ;保存在temp_sum所在的内存
    inc edi
    add dword[len_sum], 1
    sub dword[temp_len1], 1
    sub dword[temp_len2], 1
    jmp addloop
    
set_dl_0:
    mov dl, 0
    mov dword[temp_len2], 1
    jmp f2

addfinal:
    cmp byte[carry], 1
    je finalcarry
f3:    mov eax, sum
    mov ebx, len_sum
    dec edi
    jmp reverse_addresult   ;内存中加法的结果是从低位到高位存的，所以打印前先进行反转处理

reverse_addresult:
    mov dl, byte[edi]
    mov byte[eax], dl
    inc eax
    dec edi
    sub dword[len_sum], 1
    cmp dword[len_sum], 0
    je print_addresult
    
    jmp reverse_addresult
    
finalcarry:
    mov byte[edi], 49   ;最高位加起来有进位的时候，sum的最高位为1
    inc edi
    add dword[len_sum], 1
    ;  最后将carry位置0
    mov byte[carry], 0
    jmp f3
    
print_addresult:
    PRINT_STRING sum
    NEWLINE
    jmp exit
;testprint:
;   PRINT_STRING num1
;    NEWLINE
;    PRINT_STRING num2
;    NEWLINE

exit:
    mov eax, 1
    mov ebx, 0
    int 80h
    ret